#pragma once

#include <linux/compiler_attributes.h>

#define __init

/* used by init/main.c */
void setup_arch(char **);

void init_IRQ(void);
void time_init(void);
void init_timers(void);

extern void sched_init(void);

extern void kthread_daemon_init(void);

extern void call_early_init(void);
extern void call_late_init(void);

typedef int (*initcall_t)(void);

extern initcall_t __initcall_start[];
extern initcall_t __initcall_end[];

#define ____define_initcall(fn, name, sec) \
    static initcall_t name __used          \
        __attribute__((section(sec))) = fn;

#define ___define_initcall(fn, id, sec) \
    ____define_initcall(fn, __initcall##fn, sec)

#define __define_initcall(fn, id) ___define_initcall(fn, id, ".initcall." #id)

/*
 * Early initcalls run before initializing SMP.
 *
 * Only for built-in code, not modules.
 */
#define early_initcall(fn) __define_initcall(fn, 0.1)

/*
 * A "pure" initcall has no dependencies on anything else, and purely
 * initializes variables that couldn't be statically initialized.
 *
 * This only exists for built-in code, not for modules.
 * Keep main.c:initcall_level_names[] in sync.
 */
#define pure_initcall(fn) __define_initcall(fn, 1)

#define core_initcall(fn) __define_initcall(fn, 2)
#define arch_initcall(fn) __define_initcall(fn, 3)
#define subsys_initcall(fn) __define_initcall(fn, 4)
#define fs_initcall(fn) __define_initcall(fn, 5)
#define device_initcall(fn) __define_initcall(fn, 6)
#define rootfs_initcall(fn) __define_initcall(fn, 7)
#define late_initcall(fn) __define_initcall(fn, 8)

#define THIS_MODULE 0

void init_task_setup(void);
